﻿using System;
using System.ComponentModel;
using System.Web.UI;
using BbqFramework.Web.UI;
using Bbq.Gallery.UI;

namespace Bbq.Gallery
{
    public class Gallery : Control, INamingContainer
    {
		private const string RESOURCE_NAME = "Bbq.Gallery.Resource.BbqGallery.js";
        //private const string PROP_ALBUM_PARENT_ID = "AlbumParentID";

		/// <summary>
		/// Raises the <see cref="E:System.Web.UI.Control.Load"></see> event.
		/// </summary>
		/// <param name="e">The <see cref="T:System.EventArgs"></see> object that contains the event data.</param>
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			if (!ScriptManager.GetCurrent(this.Page).IsInAsyncPostBack)
			{
				ScriptReference script = new ScriptReference(
					RESOURCE_NAME, this.GetType().Assembly.FullName);
				ScriptManager.GetCurrent(this.Page).Scripts.Add(script);
			}
		}

        ///// <summary>
        ///// Gets or sets the template.
        ///// </summary>
        ///// <value>The template.</value>
        //[Category("Gallery")]
        //public string Template
        //{
        //    get
        //    {
        //        string s = (string)ViewState["Template"];
        //        return s ?? GalleryProvider.DefaultTemplate;
        //    }
        //    set { ViewState["Template"] = value; }
        //}

        ///// <summary>
        ///// Gets or sets a value indicating whether [always show navigator].
        ///// </summary>
        ///// <value><c>true</c> if [always show navigator]; otherwise, <c>false</c>.</value>
        //[Category("Gallery")]
        //public bool AlwaysShowNavigator
        //{
        //    get
        //    {
        //        object obj = (object)ViewState["AlwaysShowNavigator"];
        //        return obj == null ? true : (bool)obj;
        //    }
        //    set { ViewState["AlwaysShowNavigator"] = value; }
        //}

        /// <summary>
        /// Gets or sets the render mode.
        /// </summary>
        /// <value>The render mode.</value>
        [Category("Gallery")]
        [DefaultValue(GalleryAlbumRenderModes.Default)]
        public GalleryAlbumRenderModes RenderMode
        {
            get
            {
                object obj = ViewState["RenderMode"];
                return obj == null ? GalleryAlbumRenderModes.Default : (GalleryAlbumRenderModes)obj;
            }
            set
            {
                ViewState["RenderMode"] = value;
            }
        }

        ///// <summary>
        ///// Gets or sets a value indicating whether [auto correct image path].
        ///// </summary>
        ///// <value>
        ///// 	<c>true</c> if [auto correct image path]; otherwise, <c>false</c>.
        ///// </value>
        //[Category("Gallery")]
        //[DefaultValue(true)]
        //public bool AutoCorrectImagePath
        //{
        //    get
        //    {
        //        object obj = ViewState["AutoCorrectImagePath"];
        //        return obj == null ? true : (bool)obj;
        //    }
        //    set { ViewState["AutoCorrectImagePath"] = value; }
        //}

        ///// <summary>
        ///// Gets or sets a value indicating whether [navigate home text].
        ///// </summary>
        ///// <value><c>true</c> if [navigate home text]; otherwise, <c>false</c>.</value>
        //[Category("Gallery")]
        //[DefaultValue("Gallery Home")]
        //public string NavigateHomeText
        //{
        //    get
        //    {
        //        string s = (string)ViewState["NavigateHomeText"];
        //        return s ?? "Gallery Home";
        //    }
        //    set { ViewState["NavigateHomeText"] = value; }
        //}

        ///// <summary>
        ///// Gets or sets the separate HTML.
        ///// </summary>
        ///// <value>The separate HTML.</value>
        //[Category("Gallery")]
        //[DefaultValue("&nbsp;»&nbsp;")]
        //public string SeparateHtml
        //{
        //    get
        //    {
        //        string s = (string)ViewState["SeparateHtml"];
        //        return s ?? "&nbsp;»&nbsp;";
        //    }
        //    set { ViewState["SeparateHtml"] = value; }
        //}

        //private static Regex _regexLinkAlbum = new Regex(@"<\$\s*LinkAlbum\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexAlbumThumbnail = new Regex(@"<\$\s*AlbumThumbnail\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexItemsCount = new Regex(@"<\$\s*ItemsCount\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        ////private static Regex _regexAlbumName = new Regex(@"<\$\s*AlbumName\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexTemplateFolder = new Regex(@"<\$\s*TemplateFolder\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemThumbnail = new Regex(@"<\$\s*GalleryItemThumbnail\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemName = new Regex(@"<\$\s*GalleryItemName\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemCreatedDate = new Regex(@"<\$\s*GalleryItemCreatedDate\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemLastModified = new Regex(@"<\$\s*GalleryItemLastModified\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemSize = new Regex(@"<\$\s*GalleryItemSize\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemAuthor = new Regex(@"<\$\s*GalleryItemAuthor\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemViewLink = new Regex(@"<\$\s*GalleryItemViewLink\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryPagerLink = new Regex(@"<\$\s*GalleryPagerLink\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemDescription = new Regex(@"<\$\s*GalleryItemDescription\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryItemContextMenu = new Regex(@"<\$\s*GalleryItemContextMenu\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexGalleryAlbumContextMenu = new Regex(@"<\$\s*GalleryAlbumContextMenu\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);
        //private static Regex _regexClientID = new Regex(@"<\$\s*ClientID\s*\$>", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Singleline);

        public const string GALLERY_ALBUM_ID = "GAId";
        public const string GALLERY_ALBUM_PAGE = "GAP";
        public const string GALLERY_ITEM_ID = "GIId";
        public const string GALLERY_ITEM_COUNT = "GIC";

        //private const string GALLERY_CACHE_TEMPLATE = "Gallery_Cache_Template_";
        //private static object objectLockTemplate = new object();
        //private const string GALLERY_ITEM_CACHE_TEMPLATE = "Gallery_Item_Cache_Template_";
        //private static object objectLockItemTemplate = new object();
        //private const string GALLERY_LAYOUT_CACHE_TEMPLATE = "Gallery_Layout_Cache_Template_";
        //private static object objectLockLayoutTemplate = new object();
        //private const string GALLERY_ALL_ALBUMS_LAYOUT_CACHE_TEMPLATE = "Gallery_All_Albums_Layout_Cache_Template_";
        //private static object objectLockAllAlbumsLayoutTemplate = new object();
        //private const string GALLERY_ADD_ALBUM_CACHE_TEMPLATE = "Gallery_Add_Album_Cache_Template_";
        //private static object objectLockAddAlbumTemplate = new object();
        //private const string GALLERY_ADD_ITEM_CACHE_TEMPLATE = "Gallery_Add_Item_Cache_Template_";
        //private static object objectLockAddItemTemplate = new object();

        ///// <summary>
        ///// Builds the pager links.
        ///// </summary>
        ///// <param name="currentPage">The current page.</param>
        ///// <param name="pages">The pages.</param>
        ///// <param name="linkFormat">The link format.</param>
        ///// <returns></returns>
        //private string BuildPagerLinks(int currentPage, int pages, int showLinkTotal, string linkFormat, string currentLinkFormat)
        //{
        //    PageBase page = Page as PageBase;
        //    QueryString queryString = new QueryString(Page.Request.QueryString);
        //    int start = currentPage - (showLinkTotal >> 1);
        //    if (start < 1) start = 1;
        //    int end = start + showLinkTotal - 1;
        //    if (end > pages) end = pages;
        //    if (end - start + 1 < showLinkTotal) start = end - showLinkTotal + 1;
        //    if (start < 1) start = 1;
        //    StringBuilder sb = new StringBuilder();
        //    for (int i = start; i <= end; i++)
        //    {
        //        queryString[GALLERY_ALBUM_PAGE] = i.ToString();
        //        string url = page.MakeFriendlyPath(queryString);
        //        if (i != currentPage) sb.AppendFormat(linkFormat, url, i);
        //        else sb.AppendFormat(currentLinkFormat, url, i);

        //    }
        //    return sb.ToString();
        //}

        ///// <summary>
        ///// Makes the disable image.
        ///// </summary>
        ///// <param name="image">The image.</param>
        //private void MakeDisableImage(System.Web.UI.WebControls.Image image)
        //{
        //    image.Attributes.CssStyle[HtmlTextWriterStyle.Filter] = "Gray";
        //}

        //private string _pathToTemplate;
        //protected string PathToTemplate
        //{
        //    get
        //    {
        //        if (_pathToTemplate == null)//find out the path of template file
        //        {
        //            _pathToTemplate = string.Concat(GalleryHelper.TemplatePath, Path.AltDirectorySeparatorChar, this.Template);
        //            if (_pathToTemplate.Length == 1) _pathToTemplate = string.Empty;
        //        }
        //        return _pathToTemplate;
        //    }
        //}

        ///// <summary>
        ///// Gets the gallery album template.
        ///// </summary>
        ///// <returns></returns>
        //private ITemplate AlbumTemplate
        //{
        //    get
        //    {
        //        //Because of template technique, it's necessary to use a built-in caching.
        //        string cacheKey = string.Concat(GALLERY_CACHE_TEMPLATE, this.Template);
        //        ITemplate objTemplate = this.Page.Cache[cacheKey] as ITemplate;
        //        if (objTemplate == null)
        //        {
        //            lock (objectLockTemplate)
        //            {
        //                string path = string.Concat(PathToTemplate, Path.AltDirectorySeparatorChar, "GalleryAlbum.ascx");
        //                objTemplate = Page.LoadTemplate(path);
        //                Page.Cache.Insert(cacheKey, objTemplate,
        //                    new CacheDependency(Page.Server.MapPath(path)),
        //                    Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), CacheItemPriority.Normal, null);
        //            }
        //        }
        //        return objTemplate;
        //    }
        //}

        ///// <summary>
        ///// Gets the gallery item template.
        ///// </summary>
        ///// <returns></returns>
        //private ITemplate ItemTemplate
        //{
        //    get
        //    {
        //        string cacheKey = string.Concat(GALLERY_ITEM_CACHE_TEMPLATE, this.Template);
        //        ITemplate objItemTemplate = this.Page.Cache[cacheKey] as ITemplate;
        //        if (objItemTemplate == null)
        //        {
        //            lock (objectLockItemTemplate)
        //            {
        //                string path = string.Concat(PathToTemplate, Path.AltDirectorySeparatorChar, "GalleryItem.ascx");
        //                objItemTemplate = Page.LoadTemplate(path);
        //                Page.Cache.Insert(cacheKey, objItemTemplate,
        //                    new CacheDependency(Page.Server.MapPath(path)),
        //                    Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), CacheItemPriority.Normal, null);
        //            }
        //        }
        //        return objItemTemplate;
        //    }
        //}

        ///// <summary>
        ///// Gets the gallery layout template.
        ///// </summary>
        ///// <returns></returns>
        //private ITemplate LayoutTemplate
        //{
        //    get
        //    {
        //        string cacheKey = string.Concat(GALLERY_LAYOUT_CACHE_TEMPLATE, this.Template);
        //        ITemplate objLayoutTemplate = this.Page.Cache[cacheKey] as ITemplate;
        //        if (objLayoutTemplate == null)
        //        {
        //            lock (objectLockLayoutTemplate)
        //            {
        //                string path = string.Concat(PathToTemplate, Path.AltDirectorySeparatorChar, "GalleryLayout.ascx");
        //                objLayoutTemplate = Page.LoadTemplate(path);
        //                Page.Cache.Insert(cacheKey, objLayoutTemplate,
        //                    new CacheDependency(Page.Server.MapPath(path)),
        //                    Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), CacheItemPriority.Normal, null);
        //            }
        //        }
        //        return objLayoutTemplate;
        //    }
        //}

        ///// <summary>
        ///// Gets the gallery all albums layout template.
        ///// </summary>
        ///// <returns></returns>
        //private ITemplate AllAlbumsLayoutTemplate
        //{
        //    get
        //    {
        //        string cacheKey = string.Concat(GALLERY_ALL_ALBUMS_LAYOUT_CACHE_TEMPLATE, this.Template);
        //        ITemplate objLayoutTemplate = this.Page.Cache[cacheKey] as ITemplate;
        //        if (objLayoutTemplate == null)
        //        {
        //            lock (objectLockAllAlbumsLayoutTemplate)
        //            {
        //                string path = string.Concat(PathToTemplate, Path.AltDirectorySeparatorChar, "GalleryAllAlbumsLayout.ascx");
        //                objLayoutTemplate = Page.LoadTemplate(path);
        //                Page.Cache.Insert(cacheKey, objLayoutTemplate,
        //                    new CacheDependency(Page.Server.MapPath(path)),
        //                    Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), CacheItemPriority.Normal, null);
        //            }
        //        }
        //        return objLayoutTemplate;
        //    }
        //}

        ///// <summary>
        ///// Gets the add album template.
        ///// </summary>
        ///// <value>The add album template.</value>
        //private ITemplate AddAlbumTemplate
        //{
        //    get
        //    {
        //        string cacheKey = string.Concat(GALLERY_ADD_ALBUM_CACHE_TEMPLATE, this.Template);
        //        ITemplate objTemplate = this.Page.Cache[cacheKey] as ITemplate;
        //        if (objTemplate == null)
        //        {
        //            lock (objectLockAddAlbumTemplate)
        //            {
        //                string path = string.Concat(PathToTemplate, Path.AltDirectorySeparatorChar, "AddAlbum.ascx");
        //                objTemplate = Page.LoadTemplate(path);
        //                Page.Cache.Insert(cacheKey, objTemplate,
        //                    new CacheDependency(Page.Server.MapPath(path)),
        //                    Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), CacheItemPriority.Normal, null);
        //            }
        //        }
        //        return objTemplate;
        //    }
        //}

        ///// <summary>
        ///// Gets the add item template.
        ///// </summary>
        ///// <value>The add item template.</value>
        //private ITemplate AddItemTemplate
        //{
        //    get
        //    {
        //        string cacheKey = string.Concat(GALLERY_ADD_ITEM_CACHE_TEMPLATE, this.Template);
        //        ITemplate objTemplate = this.Page.Cache[cacheKey] as ITemplate;
        //        if (objTemplate == null)
        //        {
        //            lock (objectLockAddItemTemplate)
        //            {
        //                string path = string.Concat(PathToTemplate, Path.AltDirectorySeparatorChar, "AddItem.ascx");
        //                objTemplate = Page.LoadTemplate(path);
        //                Page.Cache.Insert(cacheKey, objTemplate,
        //                    new CacheDependency(Page.Server.MapPath(path)),
        //                    Cache.NoAbsoluteExpiration, new TimeSpan(0, 30, 0), CacheItemPriority.Normal, null);
        //            }
        //        }
        //        return objTemplate;
        //    }
        //}

        /// <summary>
        /// Creates the controls for normal mode.
        /// </summary>
        private void CreateControlsForNormalMode()
        {
            PageBase page = Page as PageBase;

			GalleryAlbum[] subAlbums = null;
            int pageIndex = 0;

            //Get the current album: AlbumID
			string realAlbumID = GalleryProvider.GetActualAlbumIdentity(Page.Request.QueryString[GALLERY_ALBUM_ID]);
			GalleryAlbum album = GalleryHelper.GetGalleryAlbumInfo(realAlbumID);

			//Get child albums
			subAlbums = GalleryProvider.GetChildAlbums(album);
			//Get gallery items
			string paramPage = Page.Request.QueryString[GALLERY_ALBUM_PAGE];
			if (!int.TryParse(paramPage, out pageIndex)) pageIndex = 1;
			//albumItems = GalleryProvider.GetPagedGalleryItems(album, pageIndex, GalleryProvider.PageSize, GalleryOrder.Name, true, out itemsCount);

			GalleryAlbumLayoutRenderer albumLayoutRenderer = new GalleryAlbumLayoutRenderer(album);
			albumLayoutRenderer.AlwaysShowNavigator = true;
			albumLayoutRenderer.ShowAllLinks = true;
			albumLayoutRenderer.PageSize = GalleryProvider.PageSize;
			albumLayoutRenderer.SubAlbumDirection = SubAlbumDirections.Bottom;
			this.Controls.Add(albumLayoutRenderer);
        }

        ///// <summary>
        ///// Creates the album context menu.
        ///// </summary>
        ///// <returns></returns>
        //private ContextMenu CreateAlbumContextMenu()
        //{
        //    return CreateAlbumContextMenu(null);
        //}

//        /// <summary>
//        /// Creates the album context menu.
//        /// </summary>
//        /// <param name="album">The album.</param>
//        /// <returns></returns>
//        private ContextMenu CreateAlbumContextMenu(GalleryAlbum album)
//        {
//            //Create context menu
//            ContextMenu contextMenu = null;
//#if CHECKROLE
//            if (Page.User.Identity.IsAuthenticated)
//#endif
//            {
//                string albumIdentity = album != null ? GalleryHelper.ResolveAlbumIdentity(album) : string.Empty;

//                contextMenu = new ContextMenu();
//                contextMenu.EnableViewState = false;
// #if CHECKROLE
//               if (Page.User.IsInRole(PageBase.ROLE_ADMIN)) //Only admin can set highlight
//#endif
//                {
//                    contextMenu.MenuItems.Add(new ContextMenuItem("Add new album", "addalbum", albumIdentity));
//                    if (albumIdentity.Length > 0)
//                    {
//                        ContextMenuItem deleteItem = new ContextMenuItem("Delete album", "deletealbum", albumIdentity);
//                        deleteItem.OnClientClick = "return confirm(\"Deleting album means you will delete all sub-albums and items. Are you sure?\");";
//                        contextMenu.MenuItems.Add(deleteItem);
//                        contextMenu.MenuItems.Add(new ContextMenuItem());
//                        ContextMenuItem item = new ContextMenuItem("Add new item", "additem", albumIdentity);
//                        //item.OnClientClick = Page.ClientScript.GetCallbackEventReference(this, "arg1", 
//                        contextMenu.MenuItems.Add(item);
//                    }
//                    contextMenu.MenuItems.Add(new ContextMenuItem());
//                }
//                //All authenticated users can download
//                contextMenu.MenuItems.Add(new ContextMenuItem("Download", "downloadalbum", albumIdentity));
//                //contextMenu.BoundControls.Add(new Button());
//                contextMenu.ItemCommand += new CommandEventHandler(contextMenu_ItemCommand);
//                this.Controls.Add(contextMenu);
//            }
//            return contextMenu;
//        }

        /// <summary>
        /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
        /// </summary>
        protected override void CreateChildControls()
        {
            //Clear all current child-controls and create new
            this.Controls.Clear();
            CreateControlsForNormalMode();
        }


		/// <summary>
		/// Gets the gallery provider.
		/// </summary>
		/// <value>The gallery provider.</value>
		public static GalleryProvider GalleryProvider
		{
			get
			{
				return GalleryHelper._provider;
			}
		}

    }

    /// <summary>
    /// 
    /// </summary>
    public enum GalleryAlbumRenderModes
    {
        Default,
        List
    }

    ///// <summary>
    ///// 
    ///// </summary>
    //public enum GalleryModes
    //{
    //    /// <summary>
    //    /// View album
    //    /// </summary>
    //    Normal,
    //    /// <summary>
    //    /// Add new album
    //    /// </summary>
    //    AddAlbum,
    //    /// <summary>
    //    /// Add new item
    //    /// </summary>
    //    AddItem
    //}
}